﻿using Autofac.Core;
using Microsoft.Extensions.DependencyInjection;

namespace _04_IOC
{
    internal interface IConnectionFactory
    {
        IConnection? CreateConnection(string name);
    }
    /// <summary>
    /// 工厂模式|命名模式
    /// </summary>
    internal class ConnectionFactory: IConnectionFactory
    {
        private readonly IServiceProvider _provider;
        private Dictionary<string, Type> _services = new Dictionary<string, Type>();
        public ConnectionFactory(IServiceProvider provider, Dictionary<string, Type> services)
        {
            _provider = provider;
            _services = services;
        }
        //这属于是构建逻辑
        public void AddConnection<TConnection>(string name)
        {
            _services.Add(name, typeof(TConnection));
        }
        //这才是工厂的核心服务
        public IConnection? CreateConnection(string name)
        {
            if (!_services.TryGetValue(name, out Type? type))
            {
                return null;
            }
            return ActivatorUtilities.CreateInstance<IConnection>(_provider, type);
        }
    }
    /// <summary>
    /// 构建器
    /// 1.提供更加丰富的构建api
    /// 2.简化工厂的创建Builder复杂了，那么工厂的创建逻辑就简单了。
    /// 3.关注点分离，Builder关注的如果创建，工厂关注的是如果提供服务
    /// 4.一般支持链式调用
    /// 5.提供一个build方法返回目标对象的实列
    /// 6.对外提供扩展
    /// </summary>
    internal class ConnectionFactoryBuilder
    {
        private Dictionary<string, Type> _services = new Dictionary<string, Type>();
      
        public ConnectionFactoryBuilder AddConnection<TConnection>(string name)
        {
            _services.Add(name,typeof(TConnection));
            return this;
        }

        /// <summary>
        /// 代之一个丰富的api
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        public ConnectionFactoryBuilder AddConnection(string name,Type type)
        {
            _services.Add(name, type);
            return this;
        }

        public IConnectionFactory Build(IServiceProvider provider)
        {
            return new ConnectionFactory(provider, _services);
        }
    }
}
